package DAO;

import java.util.List;

import modelo.Time;
import modelo.Estadio;

import connection.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TimeDAOImp implements TimeDAO {

	/**
	 * id_time, nome, estadio
	 **/
	private final String INSERT = "INSERT INTO Times(nome, id_estadio) VALUES (?,?)";
	private final String UPDATE = "UPDATE Times SET nome = ?, id_estadio = ? WHERE id_time = ?";
	private final String DELETE = "DELETE from Times WHERE id_time = ?";
	private final String ALL = "SELECT id_time, nome, id_estadio FROM Times";
	private final String LIKE = "SELECT id_time, nome, id_estadio FROM Times WHERE nome LIKE ?";
	private final String ID = "SELECT * FROM Times WHERE id_time = ?";

	private ConnectionManager connectionManager;
	private static Connection connection;

	TimeDAOImp() {
		this.openConnection();
	}

	public boolean isConnectionClose() {
		try {
			return connection.isClosed();
		} catch (SQLException ex) {
			return false;
		}
	}

	public Time salvar(Time e) {
		PreparedStatement ps = null;
		try {
			// 2 crie uma instancia de PreparedStatement
			// passe para ela a instrucao para realizar alteracoes em uma
			// registro do banco
			ps = connection.prepareStatement(INSERT);

			/**
			 * nome, id_estadio
			 */
			ps.setObject(1, e.getNome());
			ps.setObject(2, e.getEstadio().getIdEstadio());

			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(TimeDAOImp.class.getName()).log(Level.SEVERE,
					null, ex);
		} finally {
			this.closeConnection();
		}
		return e;

	}

	@Override
	public void alterar(Time e) {
		PreparedStatement ps = null;
		try {
			// 2 crie uma instancia de PreparedStatement
			// passe para ela a instrucao para realizar alteracoes em uma
			// registro do banco
			ps = connection.prepareStatement(UPDATE);
			/**
			 * id_time, nome, estadio
			 **/

			ps.setObject(1, e.getEstadio().getIdEstadio());
			ps.setObject(2, e.getNome());
			ps.setObject(3, e.getIdTime());

			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(TimeDAOImp.class.getName()).log(Level.SEVERE,
					null, ex);
		} finally {
			this.closeConnection();
		}

	}

	@Override
	public void deletar(Time e) {
		try {
			PreparedStatement ps = null;
			ps = connection.prepareStatement(DELETE);
			// 3 passe para o PreparedStatement o valor do id que deve ser
			// excluido do banco de dados
			ps.setObject(1, e.getIdTime());

			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(TimeDAOImp.class.getName()).log(Level.SEVERE,
					null, ex);
		} finally {
			this.closeConnection();
		}

	}

	@Override
	public List<Time> findAll() {
		List<Time> times = new ArrayList<Time>();

	
		EstadioDAO estadioDAO = DAOFactory.getEstadioDAO();

		List<Estadio> estadios = new ArrayList<Estadio>();

		try {
			PreparedStatement ps = null;
			ResultSet rs = null;
			ps = connection.prepareStatement(ALL);

			// 4 Obtenha uma instancia de resultset
			rs = ps.executeQuery();
			/**
			 * estadio, data, time_1, time_2, preco_geral, preco_camarote, horas
			 */
			while (rs.next()) {
				Time time = new Time();
				time.setIdTime(rs.getInt("id_time"));
				estadios = estadioDAO.buscaEstadioPorId(rs.getInt("id_estadio"));
				time.setNome(rs.getString("nome"));
				times.add(time);
				// 5 crie uma instancia de cidade com os dados
				// obtidos do banco e adicione a lista de cidadesf

			}

		} catch (SQLException ex) {
			Logger.getLogger(TimeDAOImp.class.getName()).log(Level.SEVERE,
					null, ex);
		} finally {
			this.closeConnection();
		}
		return times;
	}

	@Override
	public void openConnection() {
		if (connectionManager == null) {
			connectionManager = ConnectionManager.getInstance();
		}

		if (connection == null) {
			connection = connectionManager.getConnection();
		}

		if (isConnectionClose()) {
			connection = connectionManager.getConnection();
		}

	}

	@Override
	public void closeConnection() {
		if (connection != null && connectionManager != null) {
			if (!this.isConnectionClose()) {
				connectionManager.closeConnection(connection);
			}
		}

	}

	@Override
	public List<Time> buscaTimePorNome(Time time) {
		List<Time> times = new ArrayList<Time>();
		EstadioDAO estadio =  DAOFactory.getEstadioDAO();
		List<Estadio> estadios = new ArrayList<Estadio>();



		try {
			PreparedStatement ps = null;
			ResultSet rs = null;

			ps = connection.prepareStatement(LIKE);
			// 6 informe o parmetro para instrucao like
			ps.setObject(1, time.getNome());

			rs = ps.executeQuery();

			while (rs.next()) {
				estadios = estadio.buscaEstadioPorId(rs.getInt("id_estadio"));

				times.add(new Time(rs.getInt("id_time"), rs.getString("nome"),
						estadios.get(0)));
			}
		} catch (SQLException ex) {
			Logger.getLogger(TimeDAOImp.class.getName()).log(Level.SEVERE,
					null, ex);
		} finally {
			this.closeConnection();
		}
		return times;
	}

	@Override
	public List<Time> buscaTimePorId(Time time) {
		List<Time> times = new ArrayList<Time>();
		EstadioDAO estadio = DAOFactory.getEstadioDAO();
		List<Estadio> estadios = new ArrayList<Estadio>();

	
		try {
			PreparedStatement ps = null;
			ResultSet rs = null;

			ps = connection.prepareStatement(ID);
			// 6 informe o parmetro para instrucao ID
			ps.setObject(1, time.getIdTime());

			rs = ps.executeQuery();

			while (rs.next()) {
				estadios = estadio.buscaEstadioPorId(rs.getInt("id_estadio"));
				times.add(new Time(rs.getInt("id_time"), 
						rs.getString("nome"),
						estadios.get(0)));

			}
		} catch (SQLException ex) {
			Logger.getLogger(TimeDAOImp.class.getName()).log(Level.SEVERE,
					null, ex);
		}
		return times;
	}

}